Відповіді:
Нижче наведено десяток прикладів того, як ви можете взяти такий файл, як цей:
$ 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
порівняно новий, доданий в bash
4.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
не відповідають вашим поточним цілям.