как отключить использование раздела подкачки процессами, только если это действительно необходимо

find /mnt/test -name "*.txt" -print0 -printf "%f\0" |
xargs -0 -n 2 bash -c 'shift $1; ./thulac < $1 > /mnt/tokenized/$2' 2 1

Вы хотите передать полное имя пути также с нулевым разделителем, чтобы, когда придет время для xargs , чтобы разобрать список с нулевым разделителем, он может сделать это правильно.

В противном случае произойдет то, что полное имя пути к одному файлу будет объединено с базовым именем следующего файла, явление, которое вы наблюдали в случае нескольких имен файлов!

И затем вам нужно передать 2 аргумента за раз bash alligator , иначе он будет потреблять столько аргументов, сколько ему разрешено, но он передает вашему исполняемому файлу только первые два ./thulac .

Лучшая альтернатива - отказаться от xargs и выполнять всю свою работу в find , поскольку как таковая xargs работает с двумя аргументами за раз, что устраняет любые преимущества xargs . В этой версии мы предоставляем полный путь к bash и вычисляем имя файла самим bash , а не полагаемся на find для выполнения Это.

find /mnt/test -name "*.txt" -exec bash -c './thulac < "$1" \
  > "/mnt/tokenized/${1##*/}"' {} {} \;

Причина проблемы

1. Good case when only 1 file present
-print0  -printf '%f'

 /mnt/test/test.txt\0test.txt
 |-----------------|--------|

arg0 = /mnt/test/test.txt
arg1 = test.txt
bash -c 'thulac < $0 > /mnt/tokenized/$1'
thulac < /mnt/test/test.txt > /mnt/tokenized/test.txt

2. Error case when > 1 file present
-print0  -printf '%f'
/mnt/test/test.txt\0test.txt/mnt/test/test33.txt\0test33.txt
|-----------------|-----------------------------|----------|

arg0 = /mnt/test/test.txt
arg1 = test.txt/mnt/test/test33.txt
arg2 = test33.txt
bash -c 'thulac < $0 > /mnt/tokenized/$1'
thulac < /mnt/test/test.txt > /mnt/tokenized/test.txt/mnt/test/test33.txt

Исправить

We saw that the mixup occurred due to the absence of the delimiter '\0' in the -printf "%f"
So the correct way is:
find ... -print0 -printf "%f\0" | xargs ...
Ensuring that the list is partitioned at the right places and the 
sequence of fullpath1+file1\0fullpath2+file2\0... is maintained.

Now coming to the 'xargs' part, we write:
xargs -0 -n 2 bash -c '...' 2 1

Points to observe are the following:
   a) '-0' => arguments to xargs will be taken to be NULL separated.
   b) -n 2 => we feed 2 args at a time to bash from the total pool 
      delivered to xargs by find.
   c) 2 1 is just a best practice to get over different shell's behavior
      regarding what construes as $0, $1, $2, ...; In your particular case since you
      already know that $0 -> first arg, $1 -> 2nd arg, we could just as well have
     written what you did:
    find ... | xargs -0 -n 2 bash -c './thulac < $0 > /mnt/tokenized/$1'
1
06.11.2017, 16:52
0 ответов

Теги

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