سؤال كيف أقوم بإضافة نص إلى بداية الملف في Bash؟


مرحبا اريد ان اقتبس النص الى ملف. على سبيل المثال ، أريد إضافة المهام إلى بداية ملف todo.txt. أنا على علم echo 'task goes here' >> todo.txt ولكن هذا يضيف السطر إلى نهاية الملف (ليس ما أريده).


236
2018-02-17 03:21


الأصل


هناك إذا لم يكن هناك طريقة فعالة للقيام بذلك للملفات الكبيرة: unix.stackexchange.com/questions/87772/... - Ciro Santilli 新疆改造中心 六四事件 法轮功
@ هل يمكنك إلقاء نظرة على هذه الطريقة superuser.com/a/1352628/11116 - Evan Carroll


الأجوبة:


echo 'task goes here' | cat - todo.txt > temp && mv temp todo.txt

أو

sed -i '1s/^/task goes here\n/' todo.txt

أو

sed -i '1itask goes here' todo.txt

319
2018-02-17 03:34



أول واحد يعمل عظيم! هل تمانع في شرح المنطق؟ لست متأكدا بشكل خاص كيفية تفسير بناء الجملة. - user479534
@ user8347: Pipe (|) الرسالة (echo '...') إلى cat الذي يستخدم - (الإدخال القياسي) كملف أول و todo.txt كالثاني. cat يخلق عدة ملفات. إرسال الإخراج (>) إلى ملف مسمى temp. إذا لم تكن هناك أخطاء (&&) من عند cat ثم إعادة تسمية (mv) ال temp ملف العودة إلى الملف الأصلي (todo.txt). - Dennis Williamson
لم أكن أعرف عن هذا التركيب المحتمل في المثال الأخير من السيد ، فهل يمكن لأحدهم أن يخبرني ما هو اسم هذا النوع من التراكيب حتى أتمكن من البحث عنه أكثر؟ - Kira
@ كيرا: إن 1 يعني القيام بالأمر التالي فقط على سطر واحد من الملف و i الأمر هو إدراج. ابحث في الصفحة man تحت قسم "العناوين" وفي المقطع "Zero- أو One- العناوين". - Dennis Williamson
تضمين التغريدة sed الأمر يبدو شيء من هذا القبيل (إدراج علامة التبويب الرائدة): '1i\tSome Text'، قد تحتاج إلى مضاعفة الخط المائل العكسي (backslash). خلاف ذلك ، لهجة الخاص بك sed قد لا يتعرف \t كعلامة تبويب. - Dennis Williamson


خيار أبسط في رأيي هو:

echo -e "task goes here\n$(cat todo.txt)" > todo.txt

هذا يعمل لأن الأمر داخل $(...) يتم تنفيذه من قبل todo.txt يتم الكتابة مع > todo.txt

في حين تعمل الإجابات الأخرى بشكل جيد ، أجد من الأسهل تذكر ذلك لأني أستخدم الصدى والقطة كل يوم.

تصحيح: هذا الحل هو فكرة سيئة للغاية إذا كان هناك أي خطوط مائلة عكسية todo.txt، وذلك بفضل الشكر -e صدى العلم سوف تفسر لهم. طريقة أخرى أسهل بكثير للحصول على خطوط جديدة في سلسلة المقدمة هي ...

echo "task goes here
$(cat todo.txt)" > todo.txt

... ببساطة لاستخدام الخطوط الجديدة. من المؤكد أنها لم تعد واحدة ، لكنها في الواقع لم تكن من قبل. إذا كنت تفعل ذلك داخل نص برمجي ، وكنت قلقًا بشأن المسافة البادئة (على سبيل المثال ، يمكنك تنفيذ ذلك داخل إحدى الدالات) ، فهناك بعض الحلول التي تجعل هذا الأمر مناسبًا بشكل جيد ، بما في ذلك على سبيل المثال لا الحصر:

(echo 'task goes here' && cat todo.txt) > todo.txt
echo 'task goes here'$'\n'"$(cat todo.txt)" > todo.txt

أيضا ، إذا كنت تهتم ما إذا كان يتم إضافة السطر الجديد إلى نهاية todo.txtلا تستخدم هذه. حسنا ، ما عدا الثاني إلى الأخير. هذا لا تعبث مع النهاية.


60
2017-12-19 18:57



أنا لا أحصل على $ (...) أعدم على الإطلاق. - SCL
قد يعمل هذا بشكل أفضل (أو على الإطلاق) مع علامات اقتباس مزدوجة بدلاً من مفردة ... - ℝaphink
لن -e أيضا تحويل تسلسل الهروب داخل todo.txt؟ - mk12
Workarounds الإنتاجية -> cat: <destination filename>: ملف الإدخال هو ملف الإخراج ... - ingyhere
ستكون printf أكثر ثباتًا عبر الأنظمة الأساسية ويجب أن تعمل بشكل عام بشكل أكثر سلاسة من echo -e - Peter Berg


ال moreutils لديك أداة لطيفة تسمى sponge:

echo "task goes here" | cat - todo.txt | sponge todo.txt

سوف "تمتص" STDIN ثم تكتب إلى الملف ، مما يعني أنه لا داعي للقلق بشأن الملفات المؤقتة ونقلها.

يمكنك الحصول moreutils مع العديد من توزيعات لينكس ، من خلال apt-get install moreutilsأو على OS X باستخدام البيرةمع brew install moreutils.


27
2018-04-22 12:47





يمكنك استخدام Vim in Ex mode:

ex -s -c '1i|task goes here' -c x todo.txt
  1. 1 اختر السطر الأول

  2. i إدراج

  3. x حفظ وإغلاق


6
2018-04-11 00:23





يمكنك إنشاء ملف مؤقت جديد.

echo "new task" > new_todo.txt
cat todo.txt >> new_todo.txt
rm todo.txt
mv new_todo.txt todo.txt

قد تستخدم أيضا sed أو awk. ولكن في الأساس يحدث نفس الشيء.


4
2018-02-17 03:26



لنفترض أنك خرجت من مساحة القرص new_todo.txt يحصل مكتوب جزئيا فقط. يبدو أن الحل الخاص بك تفقد الملف الأصلي. - NPE
من نفاد مساحة القرص؟ ؛-) إنه مجرد مثال بسيط. - Keith
Keith شخص يعمل على جهاز VM لم يكن يتوقع أن يحتاج إلى محرك أقراص افتراضي كبير بشكل خاص. أو شخص يتحرك ملف كبير. في أي حال ، فإن الوسيطة الحقيقية ضد هذا هي أذونات الدليل ؛ إذا لم يكن لديك إذن لإنشاء ملفات جديدة في الدليل المعطى ، فإن الأمر الوحيد الذي سيتم تنفيذه بنجاح في البرنامج النصي هو rm من الملف الأصلي. - Parthian Shot


إذا كان الملف النصي صغيرًا بما يكفي لوضعه في الذاكرة ، فلا يلزمك إنشاء ملف مؤقت لاستبداله به. يمكنك تحميل الكل في الذاكرة وكتابته مرة أخرى إلى الملف.

echo "$(echo 'task goes here' | cat - todo.txt)" > todo.txt

من المستحيل إضافة خطوط إلى بداية الملف دون كتابة الملف بأكمله.


3
2018-01-09 22:49



فقط لطرح السؤال الواضح: أين هو الحد المسموح به لمتغيرات shell؟ - nixda
بقدر ما أنا على علم ، فإنه يقتصر فقط على مقدار الذاكرة المتوفرة. لقد ملأت المتغيرات جيدا أكثر من 100MB في الذاكرة. text=$(cat file). كن حذراً من استخدام النص فقط ، لأن متغيرات shell ليست ثنائية نظيفة mywiki.wooledge.org/BashFAQ/058 - Rucent88


لا يمكنك إدراج محتوى في بداية الملف. الشيء الوحيد الذي يمكنك القيام به هو إما استبدال المحتوى الموجود أو إلحاق bytes بعد نهاية الملف الحالي.

يتطلب أي حل لسؤالك إذن إنشاء ملف مؤقت (أو مخزن مؤقت) (على الذاكرة أو على القرص) والذي سيحل في النهاية محل الملف الأصلي.

احذر من فقدان البيانات عن طريق الحفاظ على الملف الأصلي أثناء إنشاء الملف الجديد ، إذا حدث أن يكون نظام الملفات ممتلئًا أثناء العملية. على سبيل المثال:

cat <(echo task go there) todo.txt > todo.txt.new && mv todo.txt.new todo.txt

2
2018-02-17 06:25



نرحب بالناس المظلومين لشرح دوافعهم. لا تتعارض أي من الإجابات المتبقية ، بما في ذلك الإجابة المقبولة ، في أي شيء في جوابي. - jlliagre
هذا من الصعب تحليل مثل <...> تبدو مثل الأقواس ، والتي أفترض أنها ليست كذلك. مسافة بين <و (قد يساعد؟ - dumbledad
وهذا لا يعمل بالنسبة لي. echo HOME=\"/g/Users/timregan/\" | cat - 'F:\Program Files\Git\etc\profile' يعمل لكن cat <echo HOME=\"/g/Users/timregan/\" 'F:\Program Files\Git\etc\profile' يعطي الخطأ "صدى: لا يوجد مثل هذا الملف أو الدليل" - dumbledad
dumbledad أنت تفكر في الرد. لا يوجد شيء بالنسبة لك لتحليل فيه. مسافة بين < و ال ( من شأنه كسر بناء الجملة. محاولة cat <(echo HOME=\"/g/Users/timregan/\") 'F:\Program Files\Git\etc\profile' - jlliagre


يمكنك استخدام tee:

echo 'task goes here' | cat - todo.txt | tee todo.txt

0
2017-07-08 14:16



لا لا يمكنك askubuntu.com/a/752451 - Steven Penny


GitBash + Windows10 + Multline:

هنا نسخة تسمح لك باستخدامها سلاسل متعددة الخطوط.

##############################################
## This section for demo purpose only,      ##
## So you can save entire file as           ##
## whatever.sh and run it.                  ##
##                                          ##
##############################################
> MY_TARGET_FILE.txt ##Make Or Clear File
echo "[STARTER_CONTENT]" >> MY_TARGET_FILE.txt
##############################################

## Below is main code:

##################################################
TARGET_FILE_VARIABLE="MY_TARGET_FILE.txt"
ADD_TO_HEAD_VARIABLE=$(cat << "HEREDOC_HEAD_TEXT"
//|  +-------------------------------------+   |//
//|  |                                     |   |//
//|  |     MESSAGE_FOR_HEAD_OF_FILE        |   |//
//|  |                                     |   |//
//|  +-------------------------------------+   |//
HEREDOC_HEAD_TEXT
)
##################################################
TAR=$TARGET_FILE_VARIABLE                       ##
TEX=$ADD_TO_HEAD_VARIABLE                       ##
echo "$TEX" | cat - $TAR > TEMP && mv TEMP $TAR ##
##################################################

## Expected contents of MY_TARGET_FILE.txt :
## //|  +-------------------------------------+   |//
## //|  |                                     |   |//
## //|  |     MESSAGE_FOR_HEAD_OF_FILE        |   |//
## //|  |                                     |   |//
## //|  +-------------------------------------+   |//
## [STARTER_CONTENT]

0
2017-08-04 07:04