ฉันจะผนวกข้อความไปยังจุดเริ่มต้นและจุดสิ้นสุดของไฟล์ข้อความหลายไฟล์ใน Bash ได้อย่างไร


24

ฉันมีไดเรกทอรีที่เต็มไปด้วยไฟล์ข้อความ เป้าหมายของฉันคือเพิ่มข้อความต่อท้ายและท้ายข้อความทั้งหมด ข้อความที่ไปที่จุดเริ่มต้นและจุดสิ้นสุดนั้นเหมือนกันสำหรับแต่ละไฟล์

ขึ้นอยู่กับรหัสที่ฉันได้รับจากเว็บนี่คือรหัสสำหรับต่อท้ายไฟล์:

echo -e 'var language = {\n$(cat $BASEDIR/Translations/Javascript/*.txt)' > $BASEDIR/Translations/Javascript/*.txt

นี่คือรหัสสำหรับการผนวกท้ายไฟล์ เป้าหมายคือการเพิ่มข้อความ};ที่ส่วนท้ายของแต่ละไฟล์:

echo "};" >> $BASEDIR/Translations/Javascript/*.txt

ตัวอย่างที่ฉันวาดมานั้นมีไว้สำหรับการแสดงในแต่ละไฟล์ ฉันคิดว่าฉันพยายามทำหน้าที่ในหลาย ๆ *.txtไฟล์โดยใช้สัญลักษณ์แทน,

ฉันอาจทำผิดพลาดอื่น ๆ เช่นกัน ไม่ว่าในกรณีใดฉันจะต่อท้ายข้อความไปยังจุดเริ่มต้นและจุดสิ้นสุดของไฟล์หลาย ๆ ไฟล์ได้อย่างไร

คำตอบ:


27

ในการเพิ่มข้อความลงในไฟล์คุณสามารถใช้ (ด้วยการนำ GNU ไปใช้sed):

sed -i '1i some string' file

การต่อท้ายข้อความนั้นง่ายเหมือน

echo 'Some other string' >> file

สิ่งสุดท้ายที่ต้องทำคือใส่ลงในลูปซึ่งวนซ้ำไฟล์ทั้งหมดที่คุณต้องการแก้ไข:

for file in *.txt; do
  sed -i '1i Some string' "$file" &&
  echo 'Some other string' >> "$file"
done

8

คุณสามารถใช้ GNU sed

เช่นเดียวกับที่แสดงไว้แล้วคุณสามารถแทรกบรรทัดข้อความก่อนและหลังการจับคู่บรรทัดของไฟล์ด้วยการsedใช้คำสั่งiและaตามลำดับ สิ่งที่ยังไม่ได้แสดงคือคุณสามารถทำได้ด้วยซับในหนึ่งไฟล์และหลายไฟล์พร้อมกัน

ต่อไปนี้จะแทรกบรรทัดก่อนที่แรกและหลังบรรทัดสุดท้าย1i $aแทรกจะถูกดำเนินการสำหรับไฟล์ทั้งหมดที่ตรงกับ *.txtglob

sed -i -e '1ivar language = {' -e '$a};' -- *.txt

ทั้งiและaไม่เพียงทำงานกับหมายเลขบรรทัดเท่านั้น แต่ยังใช้ได้กับทุกบรรทัดที่ตรงกับรูปแบบที่กำหนดด้วย สิ่งนี้จะแทรกความคิดเห็นเมื่อใดก็ตามที่บรรทัดมีvar y = 2;:

sed -i -- '/var y = 2;/i//initialize variable y' *.js

5

คำสั่งที่สอดคล้องกับ POSIX ทั้งหมดโดยใช้ex:

for f in *.txt; do printf '%s\n' 0a 'var language = {' . '$a' '};' . x | ex "$f"; done

หากคุณเรียกใช้printfส่วนของคำสั่งด้วยตัวเองคุณจะเห็นคำสั่งแก้ไขที่ถูกต้องซึ่งส่งผ่านไปยังex:

0a
var language = {
.
$a
};
.
x

0aหมายถึง "ผนวกข้อความหลังบรรทัดที่ 0" (กล่าวอีกนัยหนึ่งก่อนบรรทัดแรก) บรรทัดถัดไปคือข้อความตัวอักษรเพื่อ "ผนวก" หลังบรรทัด 0 จุด ( .) บนบรรทัดด้วยตัวเองจะสิ้นสุดข้อความที่จะผนวก

$a หมายถึงการต่อท้ายข้อความหลังบรรทัดสุดท้ายของไฟล์

x หมายถึงการบันทึกการเปลี่ยนแปลงและออก


2

นี่เป็นวิธีที่จะทำใน Perl:

for f in ./*txt; do
  perl -lpe 'BEGIN{print "First string"}END{print "Last string"}' "$f" > foo && 
  mv foo "$f";
done

@ StéphaneChazelasการเพิ่ม-iแทนการทดแทนไฟล์นี้ไม่ทำงานมันแค่พิมพ์ไปที่ stdout
Oleh Prypin

@OlehPrypin แน่นอนสิทธิของคุณ ลบความคิดเห็นแล้ว
Stéphane Chazelas

1

ลองใช้ex:

ex -s +'bufdo!1s/^/HEAD/|$s/$/TAIL/' -cxa *.foo

โดยที่คำสั่งคือ:

  • bufdo!รันคำสั่งด้านล่างสำหรับแต่ละบัฟเฟอร์ / ไฟล์ที่เปิด (หมายเหตุ: ไม่ใช่POSIX )
  • 1s/^/HEAD/- แทรกHEADข้อความลงในบรรทัดแรกที่จุดเริ่มต้นของบรรทัด
  • $s/$/TAIL/- ต่อท้ายTAILข้อความในบรรทัดสุดท้ายที่ท้ายบรรทัด

และข้อโต้แย้งคือ:

  • -s - โหมดเงียบ / เร็ว
  • -cxa - บันทึกบัฟเฟอร์ / ไฟล์ที่เปิดอยู่ทั้งหมดและออกจาก
  • *.foo- ไฟล์ทั้งหมดในไดเรกทอรีปัจจุบัน ( *) ที่มีการfooขยายการใช้งาน**/*.fooสำหรับ recursivity (หลังจากเปิดใช้งาน GLOBSTAR: shopt -s globstar)


1
@StevenPenny ถูกต้อง ฉันใช้คุณสมบัติที่ระบุ POSIX เท่านั้นส่วนตัวเป็นการแก้ไขสคริปต์
Wildcard

1

ด้วยการgnu awkใช้inplaceส่วนขยายและBEGINFILE/ ENDFILE:

gawk -i inplace 'BEGINFILE{print "INSERT"};ENDFILE{print "APPEND"};1' ./*.txt

1

นอกจากนี้ยังมีสิทธิ์ที่จะเป็น (พร้อมผลลัพธ์ใน.outไฟล์):

find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.out' \;

อีกตัวแปรที่ซับซ้อนมากขึ้น - ไฟล์ต้นฉบับถูกแทนที่ด้วยผลลัพธ์:

find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.tmp && mv {}.tmp {}' \; -print

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.