두 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

관련 정보