xargs의 형식화된 출력

xargs의 형식화된 출력

출력 xargs 표시 형식을 변경하고 싶습니다.

cat k.txt 
1 
2 
3 

그리고

cat k.txt | xargs 
1 2 3

1, 2, 3하지만 나는 또는 을 갖고 싶습니다 1|2|3. 어떤 제안이 있으십니까?

답변1

이러한 파일을 얻는 방법에 대한 12가지 예는 다음과 같습니다.

$ cat k.txt
1
2
3

그리고 다음 형식으로 변환합니다.

1,2,3

함께 플레이하려면 다음 명령을 사용하여 위 파일을 생성할 수 있습니다.

$ cat <<EOF > k.txt
1
2
3
EOF

아래의 예는 2개의 그룹으로 나누어져 있습니다. "작동"하고 "거의"작동하는 것. 여러 번 왜 무언가가 작동하지 않는지 이해하는 것은 왜 작동하는지 이해하는 것만큼 중요하기 때문에 이것을 생략합니다.

내가 익숙한 대부분의 스크립트 언어가 표현되어 있습니다. Perl에서 흔히 인용되는 잘 알려진 약어처럼 일부는 여러 번 표현됩니다.팀토위디.

노트:,아래 예에서 쉼표( )를 원하는 문자(예: )로 바꿀 수 있습니다 |.

"유효하다"의 예

이러한 코드 조각은 필요한 출력을 생성합니다.

주문하다 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

배쉬 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()마지막 줄의 후행 공백도 제거됩니다.

첫 번째 Ruby 예제와 첫 번째 Python 예제에서도 마찬가지입니다. 문제는 그들이 본질적으로 후행 문자를 맹목적으로 "잘라내는" 작업을 어떻게 활용하는지입니다. OP에서 제공한 예에서는 괜찮지만 이러한 유형의 라이너를 사용할 때는 작업 중인 데이터에 맞는지 확인하기 위해 주의해야 합니다.

예를 들어 샘플 파일은 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,

Bash의 while+ read내장 기능:

$ while read line; do echo -n "$line,"; done < k.txt
1,2,3,

답변2

@slm은 이미 좋은 답변을 주었지만 "xargs 출력 형식 지정"질문에서와 같이

xargs -I{} echo -n "{}|" < test.txt
  • -I"문자열 바꾸기" 옵션입니다.
  • {}출력 텍스트에 대한 자리 표시자입니다.
  • 이는 찾기에서 중괄호 쌍을 사용하는 것과 유사합니다.

후행을 제거하려면 다음을 사용하여 정리 작업을 수행 |할 수 있습니다 sed.

$ xargs -I{} echo -n "{}|" < k.txt  | sed -e 's/|$//'
1|2|3

답변3

나는 이것이 오래된 스레드라는 것을 알고 있습니다. 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'

분명히 특정 문자를 구분 기호로 사용하면 혼란이 발생할 수 있으므로 현명하게 사용하세요.

답변4

xargs <k.txt | tr \  \|

그럴 필요는 없습니다 cat. 파일 입력만 전달하면 됩니다. 다른 명령이 주어지지 않으면 xargs기본 형식이 전달됩니다 /bin/echo.(백슬래시 c-escape 해석 없음).

xargs입력 파일에서 선행/후행 공백을 제거하고 다른 공백 시퀀스를 단일 공백으로 압축합니다. 이는 에서 tr다음 으로 파일을 전달할 때를 의미합니다 xargs.

tr \\n \| <k.txt | xargs

...인쇄...

1|2|3|

...가다또 다른 방법그리고 오직매개변수xargs공간 분리는 정말..

1|2|3\n

... xargs끝에 후행 개행 문자가 인쇄되기 때문입니다.(텍스트 파일에서 요구하는 대로)tr, 그러나 그렇게 설명 되지는 않습니다 .

하지만 이 점 참고해주세요(또는 여기에 제공된 다른 솔루션)xargs입력의 참조는 고려되지 않습니다 . xargs단일/이중/백슬래시로 묶인 개행이 아닌 공백 문자는 입력으로 전달되며, 그 자체는 다음과 같이 인용될 수 있습니다.

xargs <<\IN
1    2'      3'\'      \'4
IN

1 2      3' '4

관련 정보