파일에서 .sql 항목을 삭제해야 합니다.
.class 및 .sql로 끝나는 문자열이 포함된 파일이 있습니다. 파일에서 .sql로 끝나는 문자열만 삭제하면 됩니다.
파일.txt
actual.class
actual1.class
actual2.class
actual3.class
actual4.class
test.sql
test2.sql
test3.sql
test4.sql
test5.sql
내 예상 출력 파일은 다음과 같습니다
actual.class
actual1.class
actual2.class
actual3.class
actual4.class
아래 스크립트를 사용했지만 달성하지 못했습니다.
for i in `cat file.txt` ; do
fname=`echo ${i} | cut -d "." -f1`
echo ${fname}
if file=${fname}.sql
then
sed "/${fname}.sql/d" file.txt > output_file.txt
else
exit 0
fi
done
위 스크립트는 아래 출력을 얻습니다.
actual.class
actual1.class
actual2.class
actual3.class
actual4.class
test.sql
test2.sql
test3.sql
답변1
grep
해결책:
grep -q '.\.sql$' file.txt && grep -v '\.sql$' file.txt > output_file.txt
grep
두 번째 문/명령은 첫 번째 문/명령이 종료 상태 0을 반환하는 경우에만 실행됩니다(패턴과 일치하는 사례가 발견된 경우).0
.\.sql$
최종 output_file.txt
콘텐츠:
actual.class
actual1.class
actual2.class
actual3.class
actual4.class
답변2
사용
sed
sed '/\.sql$/d' test.txt
배쉬(3.2+)의 경우
while read -r line; do [[ ! $line =~ .sql ]] && echo "$line"; done <test.txt
펄을 사용하여
perl -ni.bak -e "print unless /.sql/" test.txt
답변3
또 다른 grep, 그냥 일치를 반대로 하세요
grep -v "\.sql$" filelist
답변4
이 기사 이전에도 이미 좋은 해결책이 있다고 생각합니다. 그러나 원래 게시된 스크립트에 몇 가지 문제가 있음을 지적하고 싶습니다.
for i in $(cat ...)
기본적으로 개행 문자뿐만 아니라 공백으로 입력을 구분하기 때문에 좋지 않습니다.file
if 문은 정의되지 않았기 때문에 의미가 없습니다 . 일반적인 명령문의 경우 일반적으로 한 쌍의 대괄호 안에 내용을 묶어 를if
호출해야 합니다 .test
예를 들어,if [ $f = "abc" ]; then
. 여기에 있는 공백은 모두 필수입니다.exit 0
스크립트가 특정 줄 이후의 모든 줄을 처리하는 것을 방지합니다. 이는 의도적인 것이 아니라고 생각합니다.