두 echo 명령의 출력 사이에서 \n을 제거하는 방법은 무엇입니까?

두 echo 명령의 출력 사이에서 \n을 제거하는 방법은 무엇입니까?

각 줄에 하나의 파일 이름이 포함된 텍스트 파일이 있습니다.

111_c4l5r120.png
123_c4l4r60.png
135_c4l4r180.png
147_c4l3r60.png
15_c4l1r120.png
...

이런 형태로 변환하고 싶습니다.

111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15
...

이 코드를 사용하여:

#!/bin/bash
while IFS='' read -r line || [[  -n "$line"  ]]; do
   echo "$line" >> output.txt   
   echo "$line" | cut -d'_' -f 1 >> output.txt
done < "$1"

그러나 결과는 다음과 같습니다.

111_c4l5r120.png 
111
123_c4l4r60.png 
123
135_c4l4r180.png 
135
147_c4l3r60.png 
147
15_c4l1r120.png 
15
...

원하는 결과를 얻으려면 스크립트를 어떻게 변경해야 합니까?

답변1

쉘에서는 이런 종류의 작업을 수행하지 마십시오! 필요한 것보다 훨씬 더 복잡하고 오류가 발생하기 쉽고 훨씬 더 느립니다. 이러한 텍스트 조작을 위해 설계된 도구가 많이 있습니다. 예를 들어 sed(여기에서는 에 대한 최근 GNU 또는 BSD 구현을 가정 -E):

$ sed -E 's/([^_]*).*/& \1/' file
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15

또는 다음의 경우 sed:

$ sed 's/\([^_]*\).*/& \1/' file
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15

펄:

$ perl -pe 's/(.+?)_.*/$& $1/' file
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15

이상한:

$ awk -F_ '{print $0,$1}' file
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15

답변2

이를 위해 쉘을 사용해야 하는 특별한 필요가 없는 한,테르돈의 대답더 나은 대안을 제공합니다.

bash(스크립트의 shebang에 표시된 대로)을 사용하고 있으므로 -n다음 옵션을 사용하여 에코할 수 있습니다.

echo -n "${line} " >> output.txt
echo "$line" | cut -d'_' -f 1 >> output.txt

또는 다음을 사용하지 않고 셸 기능을 사용하여 라인을 처리할 수 있습니다 cut.

echo "${line} ${line%%_*}" >> output.txt

(두 줄 모두 교체 echo).

또는 printf트릭도 수행하고 모든 작업에서 작동합니다.POSIX 쉘, 일반적으로 더 좋습니다(참조왜 printf가 echo보다 나은가요?자세한 내용은):

printf "%s " "${line}" >> output.txt
echo "$line" | cut -d'_' -f 1 >> output.txt

또는

printf "%s %s\n" "${line}" "${line%%_*}" >> output.txt

(엄밀히 말하면 /bin/sh,echo -n휴대용이 아니다. 명시적으로 사용하고 있으므로 bash여기서는 괜찮습니다.)

답변3

여기 있어요:

#!/bin/bash

while IFS='' read -r line || [[  -n "$line"  ]]; do
   echo "$line" `echo "$line" | cut -d'_' -f 1` >> output.txt
#   echo "$line" | cut -d'_' -f 1 >> output.txt
done < "$1"

산출:

$ rm -rf output.txt
$ ./test.sh 1.1; cat output.txt
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15

관련 정보