각 줄에 하나의 파일 이름이 포함된 텍스트 파일이 있습니다.
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