Вопрос по in-place, whitespace, find, shell, removing-whitespace – Как удалить конечные пробелы для нескольких файлов?

56

Существуют ли какие-либо инструменты / одиночные строки UNIX, которые бы убирали конечные пробелы для нескольких файловin-place.

Например. тот, который может быть использован в сочетании сfind.

Возможный дубликатHow to remove trailing whitespaces with sed? jww
возможный дубликатHow to remove trailing whitespace of all files recursively? kenorb

Ваш Ответ

7   ответов
122

Ты хочешь

sed --in-place 's/[[:space:]]\+$//' file

Это удалитall Стандартные пробельные символы POSIX, включая вертикальную табуляцию и подачу формы. Кроме того, он будет выполнять замену только в том случае, если конечный пробел действительно существует, в отличие от других ответов, которые используют ноль или более совпадений (*).

--in-place это просто длинная форма-i, Я предпочитаю использовать длинную форму в сценариях, потому что она более наглядно иллюстрирует, что на самом деле делает флаг.

Это может быть легко интегрировано сfind вот так:

find . -type f -name '*.txt' -exec sed --in-place 's/[[:space:]]\+$//' {} \+
If you're on a Mac

Как указано в комментариях, вышеупомянутое не работает, если у вас не установлены инструменты GNU. Если это так, вы можете использовать следующее:

find . -iname '*.txt' -type f -exec sed -i '' 's/[[:space:]]\{1,\}$//' {} \+
Говоря о читабельности (и это все дело вкуса), но я никогда не использую-exec сfind потому что все это{}+ материал похож на шум линии. я предпочитаюfind . -type f -name '*.txt' | xargs --replace=FILE sed --in-place 's/foo/baz/' FILE но YMMV :)
Кстати, что такое \ + как найти терминатор exec? Mikko Ohtamaa
Похоже, что это также портит права доступа к файлам в Windows (работает из git bash); также вариант \ + не работает.
На MacOS X стокsed не поддерживает длинные варианты. Мне удалось заставить этот рецепт работать, установив GNU sed с помощью Homebrew (brew install gnu-sed).
Есть два вариантаfind -exec command, Первый заканчивается;, Работаетcommand один раз за каждый файлfind возвращается. Второй заканчивается+, Работаетcommand как можно меньше раз создавая список файлов для запускаcommand на. Поскольку; вариантrequires обратный слеш, чтобы избежать;Я также обычно ставлю его на+ также (хотя я не думаю, что это строго необходимо для+).
13

В отличие от других решений, которые требуют GNU sed, это должно работать на любой системе Unix, реализующей стандартные команды POSIX.

find . -type f -name "*.txt" -exec sh -c 'for i;do sed 's/[[:space:]]*$//' "$i">/tmp/.$ && mv /tmp/.$ "$i";done' arg0 {} +

Редактировать: эта слегка измененная версия сохраняет права доступа к файлам:

find . -type f -name "*.txt" -exec sh -c 'for i;do sed 's/[[:space:]]*$//' "$i">/tmp/.$ && cat /tmp/.$ > "$i";done' arg0 {} +
Очень полезно на HP-UX.
Работает безупречно на BSD!
Это работает почти идеально. Единственное, что он изменяет права доступа к файлам (по умолчанию?) 100644.
@ nacho4d Ответ обновлен, чтобы исправить эту проблему.
4

Я используюэтот исправить пробелы:

while IFS= read -r -d '' -u 9
do
    if [[ "$(file -bs --mime-type -- "$REPLY")" = text/* ]]
    then
        sed -i -e 's/[ \t]\+\(\r\?\)$/\1/;$a\' -- "$REPLY"
    else
        echo "Skipping $REPLY" >&2
    fi
done 9< <(find . \( -type d -regex '^.*/\.\(git\|svn\|hg\)

Особенности:

Keeps carriage returns (unlike [:space:]), so it works fine on Windows/DOS-style files. Only worries about "normal" whitespace - If you have vertical tabs or such in your files it's probably intentional (test code or raw data). Skips the .git and .svn VCS directories. Only modifies files which file thinks is a text file. Reports all paths which were skipped. Works with any filename. -prune -false \) -o -type f -print0)

Особенности:

Keeps carriage returns (unlike [:space:]), so it works fine on Windows/DOS-style files. Only worries about "normal" whitespace - If you have vertical tabs or such in your files it's probably intentional (test code or raw data). Skips the .git and .svn VCS directories. Only modifies files which file thinks is a text file. Reports all paths which were skipped. Works with any filename.
Я регулярно использую дотфайлы, которые нужно очистить - .bashrc, .gitignore и т. Д. Нет никаких полномочий относительно того, какие файлы вы всегда должны исключать, так что это зависит от вас и поставленной задачи.
Просто чтобы быть в безопасности: вы, вероятно, хотите игнорировать все. файлы для автоматической обработки, подобные этой (Eclipse .metadata, .bzr и т. д.) Mikko Ohtamaa
1

Как насчет этого:

sed -e -i 's/[ \t]*$//'

Кстати, это удобный сайт:http://sed.sourceforge.net/sed1line.txt

0

Почему-то команды sed и perl у меня не сработали. Это сделал:

find ./ -type f | rename 's/ +$//g'

Чувствуется как самый прямой, чтобы читать

Это вместо удаления конечных пробелов из имен файлов?
1
ex

Попробуйте использоватьБывший редактор (часть Vim):

$ ex +'bufdo!%s/\s\+$//e' -cxa *.*

Note: For recursion (bash4 & zsh), you can use новая опция globbing (**/*.*). Включить поshopt -s globstar.

perl
find . -type f -name "*.java" -exec perl -p -i -e "s/[ \t]$//g" {} \;

согласноСтиль кода Spring Framework.

sed

Для использованияsed, проверять:Как убрать конечные пробелы с помощью sed?

Смотрите также:Как рекурсивно удалить конечные пробелы из всех файлов?

Я думаю, что это"s/[ \t]+$//g" в перл.
1

Для тех, кто не является sed gurus (включая меня), я создал небольшой скрипт для использования регулярных выражений JavaScript для замены текста в файлах и выполняет замену на месте:

http://git.io/pofQnQ

Чтобы удалить конечные пробелы, вы можете использовать его следующим образом:

$ node sed.js "/^[\t ]*$/gm" "" file

наслаждаться

Похожие вопросы