ฉันต้องการเปลี่ยนรูปแบบของเอาต์พุต xargs ที่แสดง
cat k.txt
1
2
3
และ
cat k.txt | xargs
1 2 3
แต่ผมอยากจะมีหรือ1, 2, 3
1|2|3
ข้อเสนอแนะใด ๆ
ฉันต้องการเปลี่ยนรูปแบบของเอาต์พุต xargs ที่แสดง
cat k.txt
1
2
3
และ
cat k.txt | xargs
1 2 3
แต่ผมอยากจะมีหรือ1, 2, 3
1|2|3
ข้อเสนอแนะใด ๆ
คำตอบ:
ด้านล่างนี้เป็นตัวอย่างหนึ่งโหลหรือหลายวิธีที่คุณสามารถใช้ไฟล์เช่นนี้:
$ cat k.txt
1
2
3
และแปลงเป็นรูปแบบนี้:
1,2,3
คุณสามารถใช้คำสั่งนี้เพื่อสร้างไฟล์ด้านบนหากคุณต้องการเล่น:
$ cat <<EOF > k.txt
1
2
3
EOF
ตัวอย่างด้านล่างแบ่งออกเป็น 2 กลุ่ม คนที่ "ทำงาน" และคนที่ "เกือบ" ทำงาน ฉันออกไปเพราะบ่อยครั้งมันมีค่าพอที่จะดูว่าทำไมบางสิ่งบางอย่างไม่ทำงานเหมือนที่เห็นว่าทำไมบางสิ่งถึงทำ
ภาษาสคริปต์ส่วนใหญ่ที่ฉันคุ้นเคยเป็นตัวแทน บางตัวแสดงหลายครั้งเนื่องจากตัวย่อที่มีชื่อเสียงมักจะอ้างอิงใน Perl, TIMTOWTDI TIMTOWTDI
หมายเหตุ:คุณสามารถสลับเครื่องหมายจุลภาค ( ,
) ในตัวอย่างด้านล่างและแทนที่ด้วยอักขระที่คุณต้องการเช่น|
ในตัวอย่างด้านล่างและแทนที่ด้วยตัวอักษรสิ่งที่คุณต้องการคือ
ตัวอย่างโค้ดเหล่านี้จะสร้างผลลัพธ์ที่ต้องการ
paste
สั่ง:
$ paste -s -d ',' k.txt
1,2,3
sed
สั่ง:
$ sed ':a;N;$!ba;s/\n/,/g' k.txt
1,2,3
$ sed ':a;{N;s/\n/,/};ba' k.txt
1,2,3
perl
สั่ง:
$ perl -00 -p -e 's/\n(?!$)/,/g' k.txt
1,2,3
$ perl -00 -p -e 'chomp;tr/\n/,/' k.txt
1,2,3
awk
สั่ง:
$ awk '{printf"%s%s",c,$0;c=","}' k.txt
1,2,3
$ awk '{printf "%s,",$0}' k.txt | awk '{sub(/\,$/,"");print}'
1,2,3
$ awk -vORS=, 1 k.txt | awk '{sub(/\,$/,"");print}'
1,2,3
$ awk 'BEGIN {RS="dn"}{gsub("\n",",");print $0}' k.txt | awk '{sub(/\,$/,"");print}'
1,2,3
python
สั่ง:
$ python -c "import sys; print sys.stdin.read().replace('\n', ',')[0:-1]" <k.txt
1,2,3
$ python -c "import sys; print sys.stdin.read().replace('\n', ',').rstrip(',')" <k.txt
1,2,3
Bash's mapfile
ในตัว:
$ mapfile -t a < k.txt; (IFS=','; echo "${a[*]}")
1,2,3
ruby
สั่ง:
$ ruby -00 -pe 'gsub /\n/,",";chop' < k.txt
1,2,3
$ ruby -00 -pe '$_.chomp!"\n";$_.tr!"\n",","' k.txt
1,2,3
php
สั่ง:
$ php -r 'echo strtr(chop(file_get_contents($argv[1])),"\n",",");' k.txt
1,2,3
คำเตือน
ตัวอย่างข้างต้นส่วนใหญ่จะใช้งานได้ดี บางคนมีปัญหาที่ซ่อนอยู่เช่นตัวอย่าง PHP ด้านบน ฟังก์ชั่นchop()
เป็นนามแฝงจริงrtrim()
ดังนั้นช่องว่างต่อท้ายของบรรทัดสุดท้ายก็จะถูกลบออก
ตัวอย่างทับทิมแรกก็เช่นกันและตัวอย่างงูหลามแรกก็เช่นกัน ปัญหาคือว่าพวกเขาใช้ประโยชน์จากประเภทของการดำเนินงานที่เป็นหลัก "สับ" ปิด, สุ่มสี่สุ่มห้า, อักขระต่อท้าย นี่เป็นสิ่งที่ดีสำหรับตัวอย่างที่ OP ให้มา แต่ต้องระมัดระวังเมื่อใช้ liners ชนิดหนึ่งเหล่านี้เพื่อให้แน่ใจว่าสอดคล้องกับข้อมูลที่พวกเขากำลังประมวลผล
ตัวอย่าง
พูดไฟล์ตัวอย่างของเราk.txt
ดูเป็นแบบนี้แทน:
$ echo -en "1\n2\n3" > k.txt
มันดูคล้ายกัน แต่มีความแตกต่างเล็กน้อย ไม่มีการขึ้นบรรทัดใหม่ ( \n
) เหมือนไฟล์ต้นฉบับ ตอนนี้เมื่อเราเรียกใช้ตัวอย่าง Python แรกเราจะได้รับ:
$ python -c "import sys; print sys.stdin.read().replace('\n', ',')[0:-1]" <k.txt
1,2,
เหล่านี้เป็น"เสมอเพื่อนเจ้าสาวไม่เคยเจ้าสาว"ตัวอย่าง ส่วนใหญ่สามารถปรับได้ แต่เมื่อทำงานเพื่อแก้ปัญหาที่อาจเกิดขึ้นเมื่อรู้สึกว่า "ถูกบังคับ" อาจเป็นเครื่องมือที่ผิดสำหรับงาน!
perl
สั่ง:
$ perl -p -e 's/\n/,/' k.txt
1,2,3,
tr
สั่ง:
$ tr '\n' ',' < k.txt
1,2,3,
cat
+ echo
คำสั่ง:
$ echo $(cat k.txt)
1 2 3
ruby
สั่ง:
$ ruby -pe '$_["\n"]=","' k.txt
1,2,3,
while
+ read
บิวด์อินของ Bash :
$ while read line; do echo -n "$line,"; done < k.txt
1,2,3,
awk
ฉันชอบทางเลือกที่สั้นกว่า:awk -vORS=, 1 k.txt
bash
:mapfile -t a < k.txt; (IFS=','; echo "${a[*]}")
perl
และคุณawk
ก็มีพวกเขาเช่นกัน
paste
หนึ่งที่ด้านบน นั่นคือสิ่งที่paste -s
อยู่ตรงนี้ มันเป็นคำสั่งมาตรฐานและจะมีประสิทธิภาพมากที่สุด ส่วนอื่น ๆ ทั้งหมดเป็น overkill และ / หรือไม่พกพาหรือมีข้อ จำกัด
mapfile
ค่อนข้างใหม่เพิ่มในbash
4.0
@slm ได้รับคำตอบที่ดี แต่เป็นคำถามของคุณ "รูปแบบผลลัพธ์ของ xargs"
xargs -I{} echo -n "{}|" < test.txt
-I
เป็นตัวเลือก "แทนที่สตริง"{}
เป็นตัวยึดสำหรับข้อความที่ส่งออกหากคุณต้องการกำจัดร่องรอย|
คุณสามารถใช้sed
เพื่อทำความสะอาด:
$ xargs -I{} echo -n "{}|" < k.txt | sed -e 's/|$//'
1|2|3
tr
, sed
และอื่น ๆ ยัง ..
ฉันรู้ว่านี่เป็นกระทู้เก่า OP ถามด้วยรหัสง่ายๆเช่นนี้ เพื่อให้มันใกล้เคียงกับต้นฉบับฉันมีวิธีแก้ปัญหาง่ายๆ
cat k.txt | xargs
1 2 3
ใช้ sed
cat k.txt | xargs | sed 's/ /,/g'
1,2,3
หรือ
cat k.txt | xargs | sed 's/ /|/g'
1|2|3
sed สามารถดูแปลก ๆ เล็กน้อย แต่พังมันทำให้รู้สึกมาก
ใช้แทนสิ่งอื่นได้ g 'สำหรับโลก: หากไม่มีสิ่งนี้มันจะทำการทดแทนครั้งแรกในแต่ละบรรทัดใหม่ เนื่องจากคุณใช้ 'xargs' มันจะแสดงเป็นหนึ่งบรรทัด ดังนั้นคุณจะได้รับ "1,2 3"
ตัวคั่นใช้สำหรับการแยก ฉันใช้ / ตัวละคร เคล็ดลับที่น่าสนใจอย่างหนึ่ง: คุณสามารถแทนที่ตัวคั่นด้วยอักขระอื่น ๆ ส่วนใหญ่ตราบใดที่เรายังคงรูปแบบเดียวกันระหว่างเครื่องหมายคำพูด ดังนั้นมันจะทำงานได้เช่นกัน ....
cat k.txt | xargs | sed 's# #,#g'
หรือ
cat k.txt | xargs | sed 'sT T,Tg'
เห็นได้ชัดว่าการใช้ตัวอักษรบางตัวเป็นตัวคั่นอาจทำให้สับสนดังนั้นจึงต้องฉลาด
xargs <k.txt | tr \ \|
คุณไม่จำเป็นต้องcat
- เพียงแค่ผ่านในการป้อนข้อมูลไฟล์และ - ถ้าได้รับไม่มีคำสั่งอื่น ๆ - xargs
จะผ่านออกมารูปแบบเริ่มต้นของมัน - ซึ่งเป็นชนิดที่มี/bin/echo
's (โดยไม่ต้องตีความทับขวาคหนี)
xargs
จะตัดปิดช่องว่างส่วนหัว / ท้ายจากไฟล์อินพุตและบีบลำดับอื่นของช่องว่างลงไปที่ช่องว่างเดียว ซึ่งหมายความว่าในขณะที่ส่งไฟล์จากtr
ไปที่xargs
ชอบ:
tr \\n \| <k.txt | xargs
... พิมพ์ ...
1|2|3|
... จะไปทางอื่นและการดำเนินงานเฉพาะในargsว่าxargs
พื้นที่ delimits ไม่ ....
1|2|3\n
... เนื่องจากxargs
พิมพ์บรรทัดใหม่ที่ตามมาสุดท้าย(ตามที่จำเป็นสำหรับไฟล์ข้อความ)แต่ไม่ได้รับการtr
แก้ไขแบบนั้น
อย่างไรก็ตามโปรดทราบว่าสิ่งนี้(หรือโซลูชันอื่น ๆ ที่มีให้ที่นี่)ไม่ได้มีส่วนช่วยxargs
ในการอ้างอิงข้อความ xargs
จะส่งผ่านตัวอักษรช่องว่าง whitespace แบบช่องเดี่ยว / คู่ / แบ็กสแลชที่ไม่ใช่ newline ซึ่งสามารถอ้างถึงได้เช่น:
xargs <<\IN
1 2' 3'\' \'4
IN
1 2 3' '4
xargs cat -n
แต่เป็นเรื่องง่ายถ้าคุณเพียงแค่ตัดตัวอักษรขึ้นบรรทัดใหม่นี้สามารถทำได้ด้วยecho $(cat)
,grep
หรือawk
(รวบรวมข้อมูลวิธีที่จะทำมัน)xargs
ไม่เหมาะกับวัตถุประสงค์ปัจจุบันของคุณ