누군가 이것을 설명할 수 있나요?
파일이 있습니다:
cat listi.txt
sdfasdfsf123sadfasdf123
jlkjh2345ljkh245lkh4325
57hghf456ghf457gf467
여기서 sed는 첫 번째 줄을 놓쳤습니다.
while read line ; do sed 's/[^0-9]//g'; done < listi.txt
23452454325
57456457467
여기에서 확인하세요:
while read line ; do echo $line; done < listi.txt
sdfasdfsf123sadfasdf123
jlkjh2345ljkh245lkh4325
57hghf456ghf457gf467
이것은 작동하지만 중복된 느낌이 들고 sed가 모든 줄을 통과할 것이라고 생각했기 때문에 놓쳤을 수도 있습니다.
while read line ; do echo $line | sed 's/[^0-9]//g'; done < listi.txt
123123
23452454325
57456457467
왜 이런거야? bash에 대한 신뢰를 다시 얻었습니다. 왜냐하면 그것이 나를 의심하게 만들었기 때문입니다.
답변1
초기 루프:
while read line; do
sed 's/[^0-9]//g'
done <listi.txt
여기서 일어나는 일은 read
파일에서 오는 루프의 입력 스트림에서 한 줄을 읽는 것 입니다 listi.txt
. 값은 변수 line
(몇 가지 주의사항과 함께) 더 이상 사용되지 않습니다.
sed
그런 다음 입력 파일을 언급하지 않고 호출이 수행됩니다. 즉, sed
표준 입력 스트림에서 해당 파일을 읽게 됩니다.
표준 입력 스트림은 sed
루프에서 상속되므로 listi.txt
파일 끝에 도달할 때까지 두 번째 줄과 다른 모든 줄을 읽고 처리합니다.
그런 다음 루프가 read
다시 실행되지만 더 이상 읽을 내용이 없기 때문에 호출이 실패하고 루프가 종료됩니다.
listi.txt
위의 전체적인 효과는 sed
두 번째 줄부터 시작하는 파일을 처리하는 동안 파일의 첫 번째 줄을 무시하고 각 줄에서 숫자가 아닌 문자를 제거하여 터미널에 출력하는 것입니다.
sed
모든 행에 표현식을 적용 하려면 listi.txt
다음을 사용할 수 있습니다.
sed 's/[^0-9]//g' listi.txt
sed
즉, 편집 표현식이 입력 파일의 각 행에 기본적으로 적용되므로 별도의 쉘 루프를 사용할 필요가 없습니다 .
숫자가 아닌 모든 숫자를 제거하려면 tr
단일 문자 변환을 수행하는 도구인 를 사용하여 이 작업을 수행할 수도 있습니다.
tr -d -c '0-9\n' <listi.txt
이렇게 하면 입력에서 위 문자 세트의 보수( )의 일부인 모든 문자가 -d
제거됩니다 ( ; 입력을 줄로 나누는 개행 문자를 보존할 수 있으므로 여기에 포함됩니다). 이 비트는 로 쓸 수도 있으며 , 이는 현재 로케일의 모든 숫자 및 개행 문자와 일치합니다.-c
0-9\n
0-9\n
[:digit:]\n
또한 관련: