Вопрос по 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   ответов
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 {} +
@ nacho4d Ответ обновлен, чтобы исправить эту проблему.
Это работает почти идеально. Единственное, что он изменяет права доступа к файлам (по умолчанию?) 100644.
Очень полезно на HP-UX.
Работает безупречно на BSD!
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\)$' -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.
Просто чтобы быть в безопасности: вы, вероятно, хотите игнорировать все. файлы для автоматической обработки, подобные этой (Eclipse .metadata, .bzr и т. д.) Mikko Ohtamaa
Я регулярно использую дотфайлы, которые нужно очистить - .bashrc, .gitignore и т. Д. Нет никаких полномочий относительно того, какие файлы вы всегда должны исключать, так что это зависит от вас и поставленной задачи.
1

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

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

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

0

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

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

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

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

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

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