Відповіді:
Нижче наведено десяток прикладів того, як ви можете взяти такий файл, як цей:
$ cat k.txt
1
2
3
і конвертувати його у такий формат:
1,2,3
Ви можете використовувати цю команду для створення вищевказаного файлу, якщо ви хочете грати разом:
$ cat <<EOF > k.txt
1
2
3
EOF
Наведені нижче приклади розділені на 2 групи. Ті, що "працюють", і ті, що "майже" працюють. Я залишаю це, тому що часто буває так само цінно бачити, чому щось не працює, як і бачити, чому щось робить.
Представлено більшість мов сценаріїв, які я знайомий. Деякі представлені декілька разів, оскільки, як і у відомому абревіатурі, на який зазвичай посилається Perl, TIMTOWTDI .
ПРИМІТКА. Ви можете поміняти кому ( ,) у наведених нижче прикладах і замінити її будь-якими символами, які ви хочете, тобто |.
Ці фрагменти коду дадуть бажаний вихід.
pasteкоманда:
$ paste -s -d ',' k.txt
1,2,3
sedкоманда:
$ sed ':a;N;$!ba;s/\n/,/g' k.txt
1,2,3
$ sed ':a;{N;s/\n/,/};ba' k.txt
1,2,3
perlкоманда:
$ perl -00 -p -e 's/\n(?!$)/,/g' k.txt
1,2,3
$ perl -00 -p -e 'chomp;tr/\n/,/' k.txt
1,2,3
awkкоманда:
$ awk '{printf"%s%s",c,$0;c=","}' k.txt
1,2,3
$ awk '{printf "%s,",$0}' k.txt | awk '{sub(/\,$/,"");print}'
1,2,3
$ awk -vORS=, 1 k.txt | awk '{sub(/\,$/,"");print}'
1,2,3
$ awk 'BEGIN {RS="dn"}{gsub("\n",",");print $0}' k.txt | awk '{sub(/\,$/,"");print}'
1,2,3
pythonкоманда:
$ python -c "import sys; print sys.stdin.read().replace('\n', ',')[0:-1]" <k.txt
1,2,3
$ python -c "import sys; print sys.stdin.read().replace('\n', ',').rstrip(',')" <k.txt
1,2,3
mapfileВбудований Bash :
$ mapfile -t a < k.txt; (IFS=','; echo "${a[*]}")
1,2,3
rubyкоманда:
$ ruby -00 -pe 'gsub /\n/,",";chop' < k.txt
1,2,3
$ ruby -00 -pe '$_.chomp!"\n";$_.tr!"\n",","' k.txt
1,2,3
phpкоманда:
$ php -r 'echo strtr(chop(file_get_contents($argv[1])),"\n",",");' k.txt
1,2,3
Коваджі
Більшість наведених вище прикладів буде добре працювати. У деяких є приховані проблеми, як-от приклад PHP вище. Функція chop()фактично є псевдонімом rtrim(), тому пробіли останнього рядка також будуть видалені.
Так само це робить і перший приклад Ruby, і перший приклад Python. Проблема полягає в тому, як вони всі використовують тип операції, який, по суті, "відбиває" сліпого характеру. Це добре підходить для прикладу, який надав ОП, але слід бути обережним при використанні цих типів одних лайнерів, щоб переконатися, що вони відповідають даних, які вони обробляють.
Приклад
Скажіть наш зразок файлу, k.txtвиглядав так:
$ echo -en "1\n2\n3" > k.txt
Схоже, але це має одну незначну різницю. Він не має контуру нового рядка ( \n), як оригінальний файл. Тепер, коли ми запускаємо перший приклад Python, ми отримуємо це:
$ python -c "import sys; print sys.stdin.read().replace('\n', ',')[0:-1]" <k.txt
1,2,
Це приклади "завжди нареченої, ніколи не нареченої" . Більшість з них, ймовірно, могли бути адаптовані, але, працюючи на потенційному вирішенні проблеми, коли вона відчувається «вимушеною», це, мабуть, неправильний інструмент для роботи!
perlкоманда:
$ perl -p -e 's/\n/,/' k.txt
1,2,3,
trкоманда:
$ tr '\n' ',' < k.txt
1,2,3,
Команди cat+ echo:
$ echo $(cat k.txt)
1 2 3
rubyкоманда:
$ ruby -pe '$_["\n"]=","' k.txt
1,2,3,
Bash while+ readвбудовані:
$ while read line; do echo -n "$line,"; done < k.txt
1,2,3,
awkя віддаю перевагу коротшій альтернативі:awk -vORS=, 1 k.txt
bash:mapfile -t a < k.txt; (IFS=','; echo "${a[*]}")
perlі перший awkмає їх теж.
pasteсаму вгорі. Саме це і paste -sє для чого. Це стандартна команда і була б найбільш ефективною. Усі інші є надмірними та / або не портативними, або мають обмеження.
mapfileпорівняно новий, доданий в bash4.0.
@slm вже дав приємну відповідь, але як ваше питання "формат виведення xargs"
xargs -I{} echo -n "{}|" < test.txt
-I є опцією "замінити рядки".{} є заповнювачем для вихідного тексту.Якщо ви хочете позбутися від останнього, |ви можете скористатись sedочищенням:
$ xargs -I{} echo -n "{}|" < k.txt | sed -e 's/|$//'
1|2|3
tr, sedта інша також ..
Це стара нитка, я знаю. ОП запитав з таким простим кодом. Щоб воно було близьким до оригіналу, у мене є просте рішення.
cat k.txt | xargs
1 2 3
використовувати sed
cat k.txt | xargs | sed 's/ /,/g'
1,2,3
або
cat k.txt | xargs | sed 's/ /|/g'
1|2|3
sed може виглядати трохи дивно, але розбитий, має багато сенсу.
's призначений для заміни. g 'є глобальним: без цього він буде робити лише першу заміну в кожному новому рядку. Оскільки ви використовуєте 'xargs', він відображає їх як один рядок. Так ви отримаєте "1,2 3".
Роздільник використовується для розділення. Я використав / символ. Один цікавий трюк: ви можете замінити роздільник на більшість будь-яких інших символів, якщо ми зберігаємо його в тому ж форматі між цитатами. Тож це також спрацювало б….
cat k.txt | xargs | sed 's# #,#g'
або
cat k.txt | xargs | sed 'sT T,Tg'
Очевидно, що використання певних знаків як роздільника може заплутатися, тому будьте розумні.
xargs <k.txt | tr \ \|
Вам не потрібно cat- просто введіть введення файлу і - якщо йому не надана інша команда - xargsпередасть його формат за замовчуванням - який має своєрідний тип /bin/echo's (без зворотної косої інтерпретації c-escape) .
xargsзніме пробіл голови / хвоста з вхідного файлу і видавить інші послідовності пробілів до єдиного пробілу. Це означає , що при проходженні файлу з trдо xargsяк:
tr \\n \| <k.txt | xargs
... відбитки ...
1|2|3|
... піде іншим способом і працює лише над аргументами, які xargsрозмежовує простір ....
1|2|3\n
... тому що xargsдрукує остаточний останній новий рядок (як це потрібно для текстового файлу) , але він не отримує trандиляції таким чином.
Зауважте, що це (або будь-яке інше запропоноване тут рішення) не враховує xargsцитування вхідних даних. xargsбудуть витіснятись буквально одиничними / подвійними / зворотними косими рисочками, що не містять рядків пробілів у рядку, які самі можуть бути цитовані як:
xargs <<\IN
1 2' 3'\' \'4
IN
1 2 3' '4
xargs cat -n, але простіше, якщо просто обрізати символи нового рядка, цього можна досягтиecho $(cat),grepабоawk(проскакуйте спосіб це зробити).xargsне відповідають вашим поточним цілям.