Làm thế nào để làm cho xargs xử lý không gian và ký tự đặc biệt từ con mèo?


9

Tôi có filemột danh sách chứa tên. I E:

Long Name One (001)
Long Name Two (201)
Long Name Three (123)
...

với không gian và một số ký tự đặc biệt. Tôi muốn tạo các thư mục từ những tên này, tức là:

cat file | xargs -l1 mkdir

Nó làm cho các thư mục cá nhân tách bằng dấu cách, ví dụ Long, Name, One, Two, Three, thay vì Long Name One (001), Long Name Two (201), Long Name Three (123).

Làm thế nào tôi có thể làm điều đó?

Câu trả lời:


13

Sử dụng -d '\n'với xargslệnh của bạn :

cat file | xargs -d '\n' -l1 mkdir

Từ trang web:

-d delim
              Input  items  are  terminated  by the specified character.  Quotes and backslash are not special; every
              character in the input is taken literally.  Disables the end-of-file string, which is treated like  any
              other  argument.   This can be used when the input consists of simply newline-separated items, although
              it is almost always better to design your program to use --null where this is possible.  The  specified
              delimiter  may be a single character, a C-style character escape such as \n, or an octal or hexadecimal
              escape code.  Octal and hexadecimal escape codes are understood as for the printf command.    Multibyte
              characters are not supported.

Ví dụ đầu ra:

$ ls
file

$ cat file
Long Name One (001)
Long Name Two (201)
Long Name Three (123)

$ cat file | xargs -d '\n' -l1 mkdir

$ ls -1
file
Long Name One (001)
Long Name Three (123)
Long Name Two (201)

Bạn cần GNU xargs cho -dtùy chọn.
cuonglm

@cuonglm Tôi nghĩ phần lớn tìm thấy GNU xargs. Tôi cũng đã kiểm tra 1 , 2 , 3 . vâng, BSD có thể là trường hợp
Pandya


3

xargs mong đợi một định dạng đầu vào rất đặc biệt trong đó các đối số được phân cách bằng khoảng trắng hoặc dòng mới (đôi khi là các dạng khác của khoảng trắng dọc, đôi khi phụ thuộc vào miền địa phương hiện tại) và trong đó có thể sử dụng dấu ngoặc đơn, dấu ngoặc kép và dấu gạch chéo ngược để thoát chúng (nhưng khác cách từ trích dẫn vỏ).

-l1không phải là truyền một dòng đầu vào dưới dạng một đối số duy nhất mkdir, nhưng để gọi một mkdirlời gọi cho mỗi dòng đầu vào nhưng với các từ trên dòng đó vẫn được phân tách thành các đối số khác nhau mkdir.

Việc triển khai GNU xargsđã thêm một -0tùy chọn từ nhiều thập kỷ trước để chấp nhận đầu vào được phân định bằng NUL. Đó là cách rõ ràng nhất để phân tách các từ sắp kết thúc thành đối số cho một lệnh vì ký tự NUL tình cờ là ký tự duy nhất không thể xảy ra trong một đối số lệnh hoặc tên tệp (định dạng danh sách được chọn của bạn đặt một tệp trên mỗi dòng không thể đại diện cho tất cả các tên tệp có thể vì nó không cho phép một dòng mới trong một tên tệp).

Điều đó -0đã được sao chép bởi một số xargstriển khai khác nhưng không phải tất cả.

Với những người bạn có thể làm:

<file tr '\n' '\0' | xargs -0 mkdir -p --

Điều đó sẽ gọi mkdircàng ít lần càng tốt với càng nhiều đối số càng tốt.

Nhưng lưu ý rằng nếu filetrống, mkdirvẫn sẽ được chạy và bạn sẽ gặp lỗi cú pháp mkdirdo thiếu đối số. GNU xargsđã thêm một -rtùy chọn cho cái đã được sao chép bởi một vài triển khai khác.

GNU xargscũng đã thêm (sau này) một -dtùy chọn để có thể chỉ định các dấu phân cách tùy ý, nhưng tôi không nghĩ rằng bất kỳ triển khai nào khác đã sao chép nó. Với GNU xargs, cách tốt nhất là với:

xargs -rd '\n' -a file mkdir -p --

Bằng cách chuyển tệp với -a(cũng là phần mở rộng GNU) thay vì stdin, điều đó có nghĩa mkdirlà stdin của được giữ nguyên.

POSIXly, bạn cần xử lý hậu kỳ đầu vào để đặt nó ở định dạng mong đợi xargs. Bạn có thể làm điều đó với:

<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' | xargs mkdir -p --

Nơi chúng tôi đặt mỗi dòng bên trong dấu ngoặc kép và thoát từng dòng "như "\""trước khi cho xargs.

Nhưng hãy cẩn thận với những hạn chế có thể:

  • lỗi khi tập tin trống đã được đề cập ở trên
  • nó có thể thất bại với một số triển khai (bao gồm cả sed) nếu nội dung của filevăn bản không hợp lệ trong ngôn ngữ hiện tại. Nếu filechứa mã hóa tên tệp trong nhiều bộ ký tự khác nhau hoặc bộ ký tự khác với bảng địa phương, bạn có thể sửa miền địa phương thành C sẽ giúp ích.
  • một số xargstriển khai có giới hạn thấp một cách lố bịch về độ dài tối đa của một đối số (có thể thấp tới 255 byte).

Để khắc phục lỗi cú pháp khi lỗi đầu vào trống , bạn có thể viết:

<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' |
  xargs sh -c '[ "$#" -eq 0 ] || exec mkdir -p -- "$@"' sh

1

Làm cho các tên null kết thúc và phân chia ở đó:

cat file | tr '\n' '\0' | xargs -l1 -0 mkdir

trsẽ thay thế dòng mới catxuất ra \0và các -0cờ trong xargsđang bảo nó phân chia các đối số trên \0.


1

Bạn có thể thực hiện POSIXLY này với -Itùy chọn:

xargs -I % mkdir % < file

http://pub.opengroup.org/onlinepub/9699919799/utilities/xargs.html


Mặc dù nó sẽ hoạt động với mẫu của OP, nhưng bạn vẫn gặp vấn đề với các khoảng trống hàng đầu, dấu ngoặc đơn, dấu ngoặc kép và dấu gạch chéo ngược (và có thể các dòng dài và chuỗi byte không tạo thành các ký tự hợp lệ trong miền địa phương).
Stéphane Chazelas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.