Как удалить определенные слова из файлов с помощью сценария оболочки?

Я должен удалить каждое слово, содержащее хотя бы одно число из каждого файла, заданного через командную строку в качестве параметра. Это мой код:

while [ "$*" != "" ]; do
    if [ ! -f $1 ]
        then echo "$1 not file"
    else
        sed -ie  "s/[^ ]*[0-9][^ ]*//g" $1
    fi
    shift
done

Он отлично работает, если у меня есть только один файл, но если у меня есть больше, он дает одинаковый результат для каждого. После запуска скрипта в каждом файле будет результат первого.

Может кто-нибудь сказать мне, что мне не хватает?

EDIT2:

Это то, что я бегу сейчас:

while [ "$#" -ne 0 ]; do
for file in "$@"; do
    if [ ! -e "$file" ]; then
        printf "file doesn't exist: %s\n" "$file"
        continue;
    fi
    if [ ! -f "$file" ]; then
        printf "not a file: %s\n" "$file"
        continue;
    fi
done
    sed -i "s/[^ ]*[0-9][^ ]*//g" "$file"
done

Я говорил о цикле "сделано для цикла" и цикле "сделано для цикла"; но даже без этого мой скрипт продолжает работать.

РЕДАКТИРОВАТЬ:

В основном то же самое, только немного другое. Я должен удалить второе и четвертое слово из каждой строки из каждого файла (слово содержит только буквенно-цифровые символы). Это не работает должным образом, и я не могу найти ошибку. Это мой код:

while [ "$*" != "" ]; do
    if [ ! -f $1 ]
        then echo "$1 not file"
    else
        sed -ie  's/^\( *[^ ]+\) +[^ ]+\(.*\)/\1\2/
                  s/^\( *[^ ]+\)\( +[^ ]+\) +[^ ]+\(.*\)/\1\2\3/g' $1
    fi
    shift
done

1 ответ

Решение

Условие цикла while должно проверять, нет ли аргументов, и если оно есть, оно должно продолжаться. Таким образом, правильная форма будет

while [ "$#" -ne 0 ]; do

Теперь, что вы действительно хотите - это получить каждый аргумент и что-то с ним сделать. Это автоматически подразумевает цикл for. Так что вы действительно должны делать это

for file in $@; do

Теперь в файле могут быть пробелы, поэтому нужно получить имя файла и проверить, действительно ли это файл, заключить в кавычки, и вам также следует сначала проверить наличие файла.

for file in "$@"; do
    if [ ! -e "$file" ]; then
        printf "file doesn't exist: %s\n" "$file"
        continue;
    fi
    if [ ! -f "$file" ]; then
        printf "not a file: %s\n" "$file"
        continue;
    fi
    sed -i "s/[^ ]*[0-9][^ ]*//g" "$file"
done

Я мог бы расширить на sed где -i Переключатель ограничен только GNU sed. Кроме того, вы также можете сохранить резервную копию этого файла на случай, если что-то пойдет не так.
Но это другая тема, я думаю.

Другие вопросы по тегам