สมมติว่าฉันมีไฟล์ข้อความเช่น:
john
george
james
stewert
ด้วยทุกชื่อในบรรทัดแยกต่างหาก
ฉันต้องการที่จะอ่านบรรทัดของไฟล์ข้อความนี้และสร้างแฟ้มข้อความสำหรับแต่ละชื่อที่ชอบ: john.txt
, george.txt
ฯลฯ
ฉันจะทำสิ่งนี้ใน Bash ได้อย่างไร
สมมติว่าฉันมีไฟล์ข้อความเช่น:
john
george
james
stewert
ด้วยทุกชื่อในบรรทัดแยกต่างหาก
ฉันต้องการที่จะอ่านบรรทัดของไฟล์ข้อความนี้และสร้างแฟ้มข้อความสำหรับแต่ละชื่อที่ชอบ: john.txt
, george.txt
ฯลฯ
ฉันจะทำสิ่งนี้ใน Bash ได้อย่างไร
คำตอบ:
touch
:while read line; do touch "$line.txt"; done <in
while read line; [...]; done <in
: สิ่งนี้จะทำงานread
จนกว่าจะread
กลับมาเอง1
ซึ่งจะเกิดขึ้นเมื่อเมื่อถึงจุดสิ้นสุดของไฟล์ อินพุตสำหรับread
ถูกอ่านจากไฟล์ที่มีชื่อin
ในไดเร็กทอรีการทำงานปัจจุบันแทนจากเทอร์มินัลเนื่องจากการ<in
เปลี่ยนทิศทางtouch "$line.txt"
: สิ่งนี้จะทำงานtouch
ในมูลค่าที่ขยายตัวของ$line.txt
ซึ่งเป็นเนื้อหาของline
ตามด้วย.txt
; touch
จะสร้างไฟล์หากไม่มีอยู่และอัปเดตเวลาในการเข้าถึงหากมีอยู่xargs
+ touch
:xargs -a in -I name touch name.txt
-a in
: ทำให้xargs
อ่านอินพุตจากไฟล์ที่มีชื่อin
ในไดเร็กทอรีการทำงานปัจจุบัน-I name
: ทำให้xargs
แทนที่ทุกครั้งที่เกิดขึ้นname
ด้วยบรรทัดปัจจุบันของอินพุตในคำสั่งดังต่อไปนี้touch name
: ทำงานtouch
บนค่าแทนที่ของname
; มันจะสร้างไฟล์หากไม่มีอยู่และอัปเดตเวลาในการเข้าถึงหากมีอยู่% ls
in
% cat in
john
george
james
stewert
% while read line; do touch "$line.txt"; done <in
% ls
george.txt in james.txt john.txt stewert.txt
% rm *.txt
% xargs -a in -I name touch name.txt
% ls
george.txt in james.txt john.txt stewert.txt
read line
อ่านบรรทัดอย่างไร @kos
<in
หลังจากdone
ทำread
ในสภาพลูwhile
ปอ่านและเก็บหนึ่งบรรทัดจากin
ในline
ที่ซ้ำแต่ละครั้ง; ด้วยวิธีนี้touch "$line.txt"
ภายในลูปจะถูกขยายไปยังบรรทัดการอ่านด้วย.txt
ในตอนท้าย
while read line; do touch "$line.txt"; done <in
คนเดียวได้ไหม ไฟล์ต้นฉบับอยู่ที่ไหน
read
ทำงาน help read
ดู
ในกรณีนี้โดยเฉพาะที่คุณมีเพียงคำเดียวต่อบรรทัดคุณสามารถทำสิ่งต่อไปนี้
xargs touch < file
โปรดทราบว่าสิ่งนี้จะแตกถ้าชื่อไฟล์ของคุณสามารถมีช่องว่าง สำหรับกรณีดังกล่าวให้ใช้สิ่งนี้แทน:
xargs -I {} touch {} < file
เพื่อความสนุกนี่เป็นอีกสองวิธี (ซึ่งทั้งคู่สามารถจัดการชื่อไฟล์โดยพลการรวมถึงบรรทัดที่มีช่องว่าง):
Perl
perl -ne '`touch "$_"`' file
awk
awk '{printf "" > $0}' file
โปรดทราบว่าบน Linux และระบบที่คล้ายคลึงกันส่วนขยายเป็นตัวเลือกสำหรับไฟล์ส่วนใหญ่ ไม่มีเหตุผลในการเพิ่ม.txt
ส่วนขยายไปยังไฟล์ข้อความ คุณมีอิสระที่จะทำเช่นนั้น แต่มันก็ไม่ได้สร้างความแตกต่างเลย ดังนั้นหากคุณต้องการส่วนขยายใช้หนึ่งใน:
xargs -I {} touch {}.txt < file
perl -ne '`touch "$_.txt"`' file
awk '{printf "" > $0".txt"}' file
AWK เหมาะสมสำหรับงานนี้ด้วย:
testerdir:$ awk '{system("touch "$0)}' filelist
testerdir:$ ls
filelist george james john stewert
testerdir:$ awk '{system("touch "$0".txt")}' filelist
testerdir:$ ls
filelist george.txt james.txt john.txt stewert.txt
george james john stewert
อีกวิธีหนึ่ง, tee
. ขอให้สังเกตว่าวิธีการนี้จะแตกถ้าบรรทัดมีมากกว่าหนึ่งสตริงในรายการไฟล์
testerdir:$ echo "" | tee $(cat filelist)
testerdir:$ ls
filelist george james john stewert
หรือ</dev/null tee $(cat filelist)
สามารถทำได้เช่นกันหากคุณต้องการหลีกเลี่ยงการวางท่อ
cp /dev/null
วิธีการ (ตามที่ฉันแสดงให้เห็นว่าสิ่งนี้ใช้ได้กับชื่อไฟล์ที่มีช่องว่าง):
testerdir:$ cat filelist | xargs -I {} cp /dev/null "{}"
testerdir:$ ls
filelist FILE WITH SPACES george james john stewert
testerdir:$ ls FILE\ WITH\ SPACES
FILE WITH SPACES
echo "" | tee file1 file2 file2
เดียวกับ แต่มันจะพังถ้าชื่อไฟล์มีช่องว่าง
สมมติว่าฉันมีไฟล์ข้อความ ...
สมมติว่าฉันมีคำตอบ;)
awk '{system("touch \""$0".txt\"")}' file
กันน้ำยังมีช่องว่างและมีคำต่อท้าย=)