Есть ли причина, почему ls не имеет - нуль или-0 опций

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

find . -name ic_launcher.png -exec mv '{}' other_name.png ';'

или

find . -name ic_launcher.png -exec mv '{}' other_name.png \;

должен сделать то, что Вы пытаетесь сделать.

37
10.07.2018, 10:59
3 ответа

ОБНОВЛЕНИЕ (2014-02-02)

Благодаря определению нашего очень собственного @Anthon в развитии отсутствия этой функции у нас есть немного более формальная причина относительно того, почему этой функции недостает, который повторяет то, что я объяснил ранее:

Re: [PATCH] ls: adding --zero/-z option, including tests

From:      Pádraig Brady
Subject:   Re: [PATCH] ls: adding --zero/-z option, including tests
Date:      Mon, 03 Feb 2014 15:27:31 +0000

Большое спасибо за патч. Если бы мы должны были сделать это затем, это - интерфейс, который мы использовали бы. Однако ls является действительно инструментом для прямого потребления человеком, и в этом случае последующая обработка менее полезна. Для дальнейшей обработки найдите (1), больше подходит. Это хорошо описано в первом ответе в ссылке выше.

Таким образом, я был бы 70:30 против добавления этого.

Мой исходный ответ


Это - немного моего личного мнения, но я полагаю, что это проектное решение в отъезде того переключателя из ls. Если Вы замечаете find команда действительно имеет этот переключатель:

-print0
      True; print the full file name on the standard output, followed by a 
      null character (instead of the newline character that -print uses).  
      This allows file  names  that  contain  newlines or other types of white 
      space to be correctly interpreted by programs that process the find 
      output.  This option corresponds to the -0 option of xargs.

Путем пропуска того переключателя разработчики подразумевали, что Вы не должны использовать ls вывод для чего-либо кроме потребления человеком. Для нисходящей обработки другими инструментами необходимо использовать find вместо этого.

Способы использовать находят

Если Вы просто ищете альтернативные методы, можно найти их здесь, названными: Выполнение его правильно: быстрая сводка. Из той ссылки они вероятны 3 более общих шаблона:

  1. Простая находка - должностное лицо; громоздкий, если КОМАНДА является большой, и создает 1 процесс/файл:
    find . -exec COMMAND... {} \;
    
  2. Простая находка - должностное лицо с +, быстрее если несколько файлов хорошо для КОМАНДЫ:
    find . -exec COMMAND... {} \+
    
  3. Используйте находят и xargs с \0 разделителями

    (нестандартные общие расширения-print0 и-0. Работы над GNU, *BSDs, busybox)

    find . -print0 | xargs -0 COMMAND
    

Новые доказательства?

Я нашел это сообщение в блоге из блога Joey Hess названным: "ls: недостающие опции". Один из интересных комментариев в этом сообщении:

Единственное очевидное отсутствие теперь является-z опцией, которая должна заставить выходные имена файлов быть ПУСТЫЕ завершенный для consuption другими программами. Я думаю, что это было бы легко записать, но я был чрезвычайно занятым IRL (перемещающий много мебели) и не добирался до него. Какие-либо берущие для записи этого?

Далее ища я нашел это в журналах фиксации от одного из дополнительных переключателей, которые упоминает сообщение в блоге Joey, "новый выходной формат-j", таким образом, казалось бы, что сообщение в блоге дразнило понятие когда-либо добавления a -z переключатель к ls.

Относительно других опций, несколько человек соглашаются, что-e почти почти полезен, хотя ни один из нас не могу вполне найти причину использовать его. Мой отчет об ошибках забыл упоминать, что ls - eR очень ошибочен.-j является ясно шуткой.

Ссылки

37
27.01.2020, 19:36
  • 1
    . Я знаю о протестах. Никакой вопрос о выходной обработке ls не завершен, не имея, который указал на ;-) –  Timo 02.02.2014, 11:12
  • 2
    @Timo - я знаю, что Вы делаете, я делал больше для будущих читателей этого Q. Я вижу Вас на сайте, что они подошли бы в Ваших поисках к настоящему времени 8-) –  slm♦ 02.02.2014, 11:14
  • 3
    , я понял, что, и хороший, который Вы сделали. Я должен был включать ссылки на почему не (по крайней мере, только в -0 реализован) в моем вопросе, для не увода людей. –  Timo 02.02.2014, 11:19
  • 4
    Конечно, принятие там является ничем действительно экзотическим как '\n' в имени файла, ls -1 | tr '\012' '\000' перечислит файлы, разделенные Нулевыми символами. –  samiam 02.02.2014, 11:27
  • 5
    Эта статья входит в глубины filenaming проблем: dwheeler.com/essays/fixing-unix-linux-filenames.html –  slm♦ 02.02.2014, 11:40

Как ответы @slm входит в источники и возможные причины, я не повторю это здесь. Такая опция не находится на отклоненном списке функций coreutils, но патч ниже теперь отклоняется Pádraig Brady после отправки его к coreutils списку рассылки. Из ответа ясно, что это - философская причина ( ls вывод для потребления человеком).

Если Вы хотите испытать, если такая опция разумна для себя, сделайте:

git clone git://git.sv.gnu.org/coreutils
cd coreutils
./bootstrap
./configure
make

затем примените следующий патч против b938b6e289ef78815935ffa705673a6a8b2ee98e dd 2014-01-29 фиксации:

From 6413d5e2a488ecadb8b988c802fe0a5e5cb7d8f4 Mon Sep 17 00:00:00 2001
From: Anthon van der Neut <address@hidden>
Date: Mon, 3 Feb 2014 15:33:50 +0100
Subject: [PATCH] ls: adding --zero/-z option, including tests

* src/ls.c has the necessary changes to allow -z/--zero option to be
  specified, resulting in a NUL seperated list of files. This
  allows the output of e.g. "ls -rtz" to be piped into other programs

* tests/ls/no-args.sh was extended to test the -z option

* test/ls/rt-zero.sh was added to test both the long and short option
  together with "-t"

This patch was inspired by numerous questions on unix.stackexchange.com
where the output of ls was piped into some other program, invariably
resulting in someone pointing out that is an unsafe practise because of
possible newlines and other characters in the filenames.
---
 src/ls.c            |   31 +++++++++++++++++++++++++------
 tests/ls/no-arg.sh  |    7 ++++++-
 tests/ls/rt-zero.sh |   38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 7 deletions(-)
 create mode 100755 tests/ls/rt-zero.sh

diff --git a/src/ls.c b/src/ls.c
index 5d87dd3..962e6bb 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -381,6 +381,7 @@ static int file_size_width;
    many_per_line for just names, many per line, sorted vertically.
    horizontal for just names, many per line, sorted horizontally.
    with_commas for just names, many per line, separated by commas.
+   with_zero for just names, one per line, separated by NUL.

-l (and other options that imply -l), -1, -C, -x and -m control

    this parameter.  */
@@ -391,7 +392,8 @@ enum format
     one_per_line,              /* -1 */
     many_per_line,             /* -C */
     horizontal,                        /* -x */
-    with_commas                        /* -m */
+    with_commas,               /* -m */
+    with_zero,                 /* -z */
   };

static enum format format;

@@ -842,6 +844,7 @@ static struct option const long_options[] =
   {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION},
   {"context", no_argument, 0, 'Z'},
   {"author", no_argument, NULL, AUTHOR_OPTION},
+  {"zero", no_argument, NULL, 'z'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -850,12 +853,12 @@ static struct option const long_options[] =
 static char const *const format_args[] =
 {
   "verbose", "long", "commas", "horizontal", "across",
-  "vertical", "single-column", NULL
+  "vertical", "single-column", "zero", NULL
 };
 static enum format const format_types[] =
 {
   long_format, long_format, with_commas, horizontal, horizontal,
-  many_per_line, one_per_line
+  many_per_line, one_per_line, with_zero
 };
 ARGMATCH_VERIFY (format_args, format_types);

@@ -1645,7 +1648,7 @@ decode_switches (int argc, char **argv)

     {
       int oi = -1;
       int c = getopt_long (argc, argv,
-                           "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1",
+                           "abcdfghiklmnopqrstuvw:xzABCDFGHI:LNQRST:UXZ1",
                            long_options, &oi);
       if (c == -1)
         break;
@@ -1852,6 +1855,10 @@ decode_switches (int argc, char **argv)
             format = one_per_line;
           break;

+ case 'z':

+          format = with_zero;
+          break;
+
         case AUTHOR_OPTION:
           print_author = true;
           break;
@@ -2607,7 +2614,8 @@ print_dir (char const *name, char const *realname, bool 
command_line_arg)
                  ls uses constant memory while processing the entries of
                  this directory.  Useful when there are many (millions)
                  of entries in a directory.  */
-              if (format == one_per_line && sort_type == sort_none
+              if ((format == one_per_line || format == with_zero)
+                      && sort_type == sort_none
                       && !print_block_size && !recursive)
                 {
                   /* We must call sort_files in spite of
@@ -3598,6 +3606,14 @@ print_current_files (void)
         }
       break;

+ case with_zero:

+      for (i = 0; i < cwd_n_used; i++)
+        {
+          print_file_name_and_frills (sorted_file[i], 0);
+          putchar ('\0');
+        }
+      break;
+
     case many_per_line:
       print_many_per_line ();
       break;
@@ -4490,6 +4506,7 @@ print_many_per_line (void)
           indent (pos + name_length, pos + max_name_length);
           pos += max_name_length;
         }
+      putchar ('X'); // AvdN
       putchar ('\n');
     }
 }
@@ -4780,7 +4797,8 @@ Sort entries alphabetically if none of -cftuvSUX nor 
--sort is specified.\n\
   -F, --classify             append indicator (one of */=>@|) to entries\n\
       --file-type            likewise, except do not append '*'\n\
       --format=WORD          across -x, commas -m, horizontal -x, long -l,\n\
-                               single-column -1, verbose -l, vertical -C\n\
+                               single-column -1, verbose -l, vertical -C,\n\
+                               zeros -z\n\
       --full-time            like -l --time-style=full-iso\n\
 "), stdout);
       fputs (_("\
@@ -4888,6 +4906,7 @@ Sort entries alphabetically if none of -cftuvSUX nor 
--sort is specified.\n\
   -X                         sort alphabetically by entry extension\n\
   -Z, --context              print any security context of each file\n\
   -1                         list one file per line\n\
+  -z, --zero                 list files separated with NUL\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
diff --git a/tests/ls/no-arg.sh b/tests/ls/no-arg.sh
index e356a29..da28b96 100755
--- a/tests/ls/no-arg.sh
+++ b/tests/ls/no-arg.sh
@@ -30,11 +30,16 @@ out
 symlink
 EOF

-

 ls -1 > out || fail=1

compare exp out || fail=1 +/bin/echo -en "dir\00exp\00out\00symlink\00" > exp || framework_failure_

+
+ls --zero > out || fail=1
+
+compare exp out || fail=1
+
 cat > exp <<\EOF
 .:
 dir
diff --git a/tests/ls/rt-zero.sh b/tests/ls/rt-zero.sh
new file mode 100755
index 0000000..cdbd311
--- /dev/null
+++ b/tests/ls/rt-zero.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+# Make sure name is used as secondary key when sorting on mtime or ctime.
+
+# Copyright (C) 1998-2014 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ ls touch
+
+date=1998-01-15
+
+touch -d "$date" c || framework_failure_
+touch -d "$date" a || framework_failure_
+touch -d "$date" b || framework_failure_
+
+
+ls -zt a b c > out || fail=1
+/bin/echo -en "a\00b\00c\00" > exp
+compare exp out || fail=1
+
+rm -rf out exp
+ls -rt --zero a b c > out || fail=1
+/bin/echo -en "c\00b\00a\00" > exp
+compare exp out || fail=1
+
+Exit $fail
--
1.7.9.5

За другим сделайте, можно протестировать его с:

  src/ls -rtz | xargs -0 -n1 src/ls -ld

Таким образом, патч действительно работает, и я не вижу причины, почему он не был бы, но это не доказательство нет никакой технической причины для игнорирования опции. ls -R0 не мог бы иметь большого смысла, но ни один не делает ls -Rm который ls может оставить поле.

20
27.01.2020, 19:36
  • 1
    Наличие -z и --zero больше соответствует виду (также в coreutils. –  Anthon 03.02.2014, 15:51

Если у вас есть GNU xargs (от coreutils ), вы можете запустить:

$ ls … |xargs -d "\n" …

В противном случае, после того как вы подтвердите, что ваша версия xargsподдерживает-0(большинство, но спецификация POSIX для xargs даже не упоминает об этом ), вы можете запустить:

$ ls … |tr "\n" "\000" |xargs -0 …

Мой ~/.aliasesфайл, который я получил от моего ~/.bashrcи моего ~/.zshrcи который существует во всех системах, которые я использую (, поэтому требуется широкая совместимость ), содержит это:

# Like `find... -print0 |xargs -0` for programs that don't have a -print0
xargsn() {  # defer definition until first use
  if xargs --help 2>&1 |grep -Fqw "d, --delimiter"; then  # GNU
    xargsn() { xargs -d "\n" "$@"; }
  else
    # warning, xargs -0 isn't POSIX, but GNU, BSD/OSX, and Busybox support it
    xargsn() { tr "\n" "\000" |xargs -0 "$@"; }
  fi
  xargsn "$@"
}
if command -v compdef >/dev/null 2>&1; then compdef xargsn=xargs; fi # for zsh

Это откладывает вызов xargs --helpдо первого запуска xargsn, чтобы ускорить мой (довольно длинный )файл псевдонимов, то есть он проверяет GNU xargs при первом вызове, а затем сохраняет что с тех пор. После установки определения (, которое довольно быстро, ~0,02 секунды ), он затем завершает этот первый запрос как однократный -рекурсивный вызов.

Эта последняя строка указывает оболочке Z -завершить xargsn, как если бы это было xargs(, поскольку это ).

Эта xargsnфункция работает для любой команды, если вы не перебираете элементы, которые могут содержать разрывы строк. Предупреждение :Имена файлов во многих файловых системах технически могут содержать разрывы строк.Будьте уверены, что вы не допустите ничего катастрофического, если у вас такое имя файла. (См. также аргументы «не анализировать ls».)

0
10.03.2020, 17:28

Теги

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