Why does grep -r --include=*.js * > dirname/.filename not write all .js files to a single file?

262
user5448026

I am trying to put all js files in a directory and sub directorys into a single file in lexical order. What did I do wrong?

1
Будет ли `cat $ (найти ./ -type f -name" * .js "| sort)> dirname / .filename` работать для вас? txtechhelp 8 лет назад 2
@txtechhelp спасибо. это близко, но файлы с именами 2.js и 3.js помещаются над файлом /dirname/1.js. Если это можно исправить, это будет работать отлично. user5448026 8 лет назад 0
Я могу просто поставить 1 перед именем dir, но было бы хорошо, если бы этого не было. user5448026 8 лет назад 0
Вам нужно включить имя в вашем списке? Или вам нужно иметь только имена файлов, откуда они берутся? 8 лет назад 0

1 ответ на вопрос

0
ams

grep is the wrong tool for this, partly because it only emits lines from those files that match the pattern you give (and presumably you want all the lines), and partly because you didn't give a pattern, so it's using the first filename as the pattern (which is not helpful).

Listing all *.js files is easy enough:

find . -name '*.js' 

And concatenating them into one file is easy too:

find . -name '*.js' | xargs cat 

But, sorting them according to lexical order of just the filename, disregarding whatever directory they may be in, is harder.

Just plain sort won't do the job, and there's no --key option that will select the last field when the number of fields is unknown.

The following uses sed to move the filename to the start of the line, sorts that, and then strips it back off again.

find . -name '*.js' | sed 's:^.*/\([^/]*\)$:\1 \0:' | sort | cut -d' ' -f2- 

This will not work correctly if any of your file or directory names have spaces.

You can then extract the contents by adding a cat:

find . -name '*.js' \ | sed 's:^.*/\([^/]*\)$:\1 \0:' | sort | cut -d' ' -f2- \ | xargs cat